iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
自我挑戰組

一個令我自豪的App完成之路系列 第 19 篇

AVFoundation 來看看 Day 19

  • 分享至 

  • xImage
  •  

在第17天,做了一個ISBN 查詢 書本的書名、書本描述

那麼今天我希望做一個使用拍照掃描辨識出ISBN碼,這樣就不用手動輸入ISBN碼

使用Vision套件

import Vision

主要是透過apple 發布的Vision套件來辨識

透過Vision套件來做也需要一個相機的View來使用Vision套件

今天先來使用建立相機View

使用AVFoundation套件來建立相機View

// 使用AVFoundation建立相機View
import AVFoundation

https://i.imgur.com/1lJ9KxX.png

  • AVCaptureSession:AVFoundation的核心,用來Capture跟Coordinate Data flow
  • AVCaptureDevice:獲得硬體設備
  • AVCapturePhotoOutput: Photo的輸出
  • AVCaptureVideoPreviewLayer:Preview的Layer

使用的三個func來建構

  • checkPermission():來確保相機都是可以使用的
  • ConfigLiveView():來設定好相機以及資料流
  • addButton():新增拍攝Button進入View
func checkPermission(){
	let mediaType = AVMediaType.video
	// authorizationStatus回傳一個常數看是否能夠使用某個(mediaType)類型
	let status = AVCaptureDevice.authorizationStatus(for: mediaType)
	
	switch status{
		case .denied,.restricted:
			// 如果不能使用,則會出現提示來要求權限
			let Noauthorized = UIAlertController(title:"Error", message: "", preferredstyle: .alert)
			Noauthorized.addAction(UIAlertAction(title:"Set", style: .default){
							let setting = URL(string:UIApplication.openSettingsURLString)!
							UIApplication.shared.open(setting)
							}
		default:
			break

		}

}

ConfigLiveView(){

func ConfigLiveView(){
	// 最重要的部分,Session負責管理Capture & DataFlow
	captureSession = AVCaptureSession()
	// 規範Capture的資料要是什麼解析度
	captureSession.sessionPresent = .hd1920x1080

	// 開始Capture Device 
	// 使用DiscoverySession來將符合資料的Device資料儲存
	let deviceDiscoverySession = AVCaptureDevice.DiscoverytSession(deviceTypes:[AVCaptureDevice.DeviceType.builtInDualCamera],mediaType:AVMediaType.video, position: .back)
	
	// 所有符合資料的Device
	let devices = deviceDiscoverySession.devices
	for device in devices{
		if device.position == AVCaptureDevice.Postion.back{
				// 將符合資料的儲存進backCamera內
				backCamera = device
		}
	}

// 設定Input & Output
	do{
		// 讓AVCaptureDeviceInput類的資料為backCamera儲存至captureDeviceInput
		let captureDeviceInput = try AVCaptureDeviceInput(device:backCamera)
		captureSession.addInput(captureDeviceInput)
		}catch{
			showAlert(withTitle:"Camera Error")
			return
		}
	catureOutput = AVCapturePhotoOutput()
	// 設定好拍攝設定
	captureOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSetting(format:[AVVideoCodeKey:AVVideoCodecType.jpeg)
	captureSession.addOuptut(captureOutput!)

// 增加Preview Layer
	cameraPreviewLayer = AVCaptureVideoPreviewLayer(session:captureSession)
	cameraPreviewLayer?.videoGravity = .resizeAspectFill
	cameraPreviewLayer?.connection.videoOrientation = .portrait
	cameraPreviewLayer?.frame = view.frame
// The sublayer to be inserted into the current layer.
	self.view.layer.insertlayer(cameraPreviewLayer!,at:0)

	captureSession.startRunning()

}

addButton()

func addButton(){

	let width:CGFloat = 75
	let height = width
	button = UIButton(frame:CGRect(x: (view.frame.width - width)/2, y: view.frame.height - height - 32, width: width, height: height))
	button.backgroundColor = UIColor.white
	button.showsTouchWhenHighlighted = true
	button.addTarget(self,action: #selector(captureImage), for: .touchUpInside)
	view.addSubView(button)
}

captureImage() 用來Capture照片

// Capture
@objc func captureImage(){
	let setting = AVCapturePhotoSettings()
	captureOutput?.capturePhoto(with:setting, delegate: self)
}
	

showAlert() 用來作為提示用

func showAlert(withTitle: String){
	let UIAlertController(title:withTitle, message:"", preferredStyle: .alert)
	alertController.addAction(UIAlertAction(title:"OK", style: .default, handler:nil))
	present(alertController,animated:true,completion:nil)
}

參考網址:

程式碼都是參考自

Github

加上了一點自己DIY的理解

iOS AVCaptureSession学习笔记(一)

Apple Developer Documentation

iOS拍照定制之AVCapturePhotoOutput

Apple Developer Documentation
Apple Developer Documentation


上一篇
UISearchController 出來挑土豆 Day 18
下一篇
ISBN Barcode Scanner實作 Day 20
系列文
一個令我自豪的App完成之路 共 32 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言